home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 August: Tool Chest / Dev.CD Aug 98 TC.toast / Sample Code / Development Tools & Languages / AppsToGo / DTS.Lib / StringUtils.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-22  |  14.2 KB  |  731 lines  |  [TEXT/MPS ]

  1. /*
  2. **    Apple Macintosh Developer Technical Support
  3. **
  4. **    Collection of String Utilities for DTS Sample code
  5. **
  6. **    File:        StringUtils.c
  7. **
  8. **    Copyright © 1988-1993 Apple Computer, Inc.
  9. **    All rights reserved.
  10. */
  11.  
  12. /* You may incorporate this sample code into your applications without
  13. ** restriction, though the sample code has been provided "AS IS" and the
  14. ** responsibility for its operation is 100% yours.  However, what you are
  15. ** not permitted to do is to redistribute the source as "DSC Sample Code"
  16. ** after having made changes. If you're going to re-distribute the source,
  17. ** we require that you make it clear in the source that the code was
  18. ** descended from Apple Sample Code, but that you've made changes. */
  19.  
  20. #ifndef __MEMORY__
  21. #include <Memory.h>
  22. #endif
  23.  
  24. #ifndef __STRINGUTILS__
  25. #include "StringUtils.h"
  26. #endif
  27.  
  28.  
  29.  
  30. /* These functions should be linked into whatever segment holds main().  This will
  31. ** guarantee that the functions will always be in memory when called.  It is important
  32. ** that they are in memory, because if a pointer is passed in that points into an
  33. ** unlocked handle, the mere fact that the code needs to get loaded may cause the
  34. ** handle that is pointed into to move.  If you stick to these string functions,
  35. ** you will not have to worry about the handle moving when the string function is
  36. ** called.  If you have your own string functions, and you wish the same safety
  37. ** factor, link the string handling code into the same segment as main(), as you
  38. ** do with these string functions. */
  39.  
  40. static short    gBase;
  41. static Boolean    gHandleChars;
  42.  
  43.  
  44.  
  45. /*****************************************************************************/
  46. /*****************************************************************************/
  47.  
  48. #ifdef applec
  49. #pragma segment ATGStringUtils
  50. #endif
  51.  
  52. /*****************************************************************************/
  53. /*****************************************************************************/
  54.  
  55.  
  56.  
  57. /* Return the length of the c-string.  (Same as strlen, but this function isn't
  58. ** part of the string library.  The entire library may be more than you wish to
  59. ** link into the code segment that holds main, so this (and other) standard
  60. ** library function has been duplicated here. */
  61.  
  62. short    clen(char *cptr)
  63. {
  64.     short    i;
  65.  
  66.     for (i = 0; cptr[i]; ++i) {};
  67.     return(i);
  68. }
  69.  
  70.  
  71.  
  72. /*****************************************************************************/
  73.  
  74.  
  75.  
  76. /* Catenate two c-strings. */
  77.  
  78. char    *ccat(char *s1, char *s2)
  79. {
  80.     ccpy(s1 + clen(s1), s2);
  81.     return(s1);
  82. }
  83.  
  84.  
  85.  
  86. /*****************************************************************************/
  87.  
  88.  
  89.  
  90. /* Copy a c-string. */
  91.  
  92. char    *ccpy(char *s1, char *s2)
  93. {
  94.     char    *c1, *c2;
  95.  
  96.     c1 = s1;
  97.     c2 = s2;
  98.     while ((*c1++ = *c2++) != 0) {};
  99.     return(s1);
  100. }
  101.  
  102.  
  103.  
  104. /*****************************************************************************/
  105.  
  106.  
  107.  
  108. /* Compare two pascal-strings. */
  109.  
  110. short    pcmp(StringPtr s1, StringPtr s2)
  111. {
  112.     short    i, len;
  113.     char    j;
  114.  
  115.     if ((len = s1[0]) > s2[0]) len = s2[0];
  116.  
  117.     for (i = 1; i <= len; ++i) {
  118.         j = s1[i] - s2[i];
  119.         if (j) return(j);
  120.     }
  121.  
  122.     return(s1[0] - s2[0]);
  123. }
  124.  
  125.  
  126.  
  127. /*****************************************************************************/
  128.  
  129.  
  130.  
  131. /* Catenate two pascal-strings. */
  132.  
  133. void    pcat(StringPtr d, StringPtr s)
  134. {
  135.     short    i, j;
  136.  
  137.     if (((j = s[0]) + d[0]) > 255)
  138.         j = 255 - d[0];
  139.             /* Limit dest string to 255. */
  140.  
  141.     for (i = 0; i < j;) d[++d[0]] = s[++i];
  142. }
  143.  
  144.  
  145.  
  146. /*****************************************************************************/
  147.  
  148.  
  149.  
  150. /* Copy a pascal-string. */
  151.  
  152. void    pcpy(StringPtr d, StringPtr s)
  153. {
  154.     short    i;
  155.  
  156.     i = *s;
  157.     do {
  158.         d[i] = s[i];
  159.     } while (i--);
  160. }
  161.  
  162.  
  163.  
  164. /*****************************************************************************/
  165.  
  166.  
  167.  
  168. /* Convert a c-string to a pascal-string. */
  169.  
  170. void    c2p(char *cptr)
  171. {
  172.     char    len;
  173.  
  174.     BlockMove(cptr, cptr + 1, len = clen(cptr));
  175.     *cptr = len;
  176. }
  177.  
  178.  
  179.  
  180. /*****************************************************************************/
  181.  
  182.  
  183.  
  184. /* Convert a pascal-string to a c-string. */
  185.  
  186. void    p2c(StringPtr cptr)
  187. {
  188.     unsigned char    len;
  189.  
  190.     BlockMove(cptr + 1, cptr, len = *cptr);
  191.     cptr[len] = 0;
  192. }
  193.  
  194.  
  195.  
  196. /*****************************************************************************/
  197. /*****************************************************************************/
  198. /*****************************************************************************/
  199.  
  200.  
  201.  
  202. /* Catenate a single character multiple times onto the designated string. */
  203.  
  204. void    ccatchr(char *cptr, char c, short count)
  205. {
  206.     ccpychr(cptr + clen(cptr), c, count);
  207. }
  208.  
  209.  
  210.  
  211. /*****************************************************************************/
  212.  
  213.  
  214.  
  215. /* Convert the value into text for the base-10 number and catenate it to
  216. ** the designated string.  The value is assumed to be signed.  If you wish
  217. ** to have an unsigned decimal value, call ccatnum with a base of 10. */
  218.  
  219. void    ccatpaddec(char *cptr, char padChr, short minApnd, short maxApnd, long v)
  220. {
  221.     ccatpadnum(cptr + clen(cptr), padChr, minApnd, maxApnd, v, -10);
  222.         /* Catenate value base 10, signed. */
  223. }
  224.  
  225. void    ccatdec(char *cptr, long v)
  226. {
  227.     ccatnum(cptr, v, -10);
  228. }
  229.  
  230.  
  231.  
  232. /*****************************************************************************/
  233.  
  234.  
  235.  
  236. /* Convert the value into text for base-16, format it, and catenate it to the
  237. ** designated string.  ccatnum could be used, since it handles multiple bases,
  238. ** but ccathex allows for additional common formatting and padding of the
  239. ** hex value. */
  240.  
  241. void    ccatpadhex(char *cptr, char padChr, short minApnd, short maxApnd, long v)
  242. {
  243.     char    str[33], *sptr;
  244.     short    len;
  245.  
  246.     cptr += clen(cptr);            /* We're appending, so point to the end of the string. */
  247.     ccpynum(str, v, 16);        /* Generate minimum-digit hex value. */
  248.  
  249.     if ((len = clen(sptr = str)) > maxApnd)
  250.         sptr = str + len - maxApnd;
  251.  
  252.     if ((len = clen(sptr)) < minApnd)
  253.         if (padChr)
  254.             ccatchr(cptr, padChr, (minApnd - len));
  255.                 /* if we have a pad character, and if necessary, pad the string. */
  256.  
  257.     ccat(cptr, sptr);            /* Add the hex digits to the string. */
  258. }
  259.  
  260. void    ccathex(char *cptr, long v)
  261. {
  262.     ccatpadhex(cptr, 0, 0, 8, v);
  263. }
  264.  
  265.  
  266.  
  267. /*****************************************************************************/
  268.  
  269.  
  270.  
  271. /* Convert the value into text for the designated base.  Catenate the text to
  272. ** the designated string. */
  273.  
  274. void    ccatpadnum(char *cptr, char padChr, short minApnd, short maxApnd, long v, short base)
  275. {
  276.     ccpypadnum(cptr + clen(cptr), padChr, minApnd, maxApnd, v, base);
  277. }
  278.  
  279. void    ccatnum(char *cptr, long v, short base)
  280. {
  281.     ccpynum(cptr + clen(cptr), v, base);
  282. }
  283.  
  284.  
  285.  
  286. /*****************************************************************************/
  287.  
  288.  
  289.  
  290. void    ccpychr(char *cptr, char c, short count)
  291. {
  292.     for (;count--; ++cptr) *cptr = c;
  293.     *cptr = 0;
  294. }
  295.  
  296.  
  297.  
  298. /*****************************************************************************/
  299.  
  300.  
  301.  
  302. void    ccpypaddec(char *cptr, char padChr, short minApnd, short maxApnd, long v)
  303. {
  304.     ccpypadnum(cptr, padChr, minApnd, maxApnd, v, -10);
  305. }
  306.  
  307. void    ccpydec(char *cptr, long v)
  308. {
  309.     ccpynum(cptr, v, -10);
  310. }
  311.  
  312.  
  313.  
  314. /*****************************************************************************/
  315.  
  316.  
  317.  
  318. void    ccpypadhex(char *cptr, char padChr, short minApnd, short maxApnd, long v)
  319. {
  320.     cptr[0] = 0;
  321.     ccatpadhex(cptr, padChr, minApnd, maxApnd, v);
  322. }
  323.  
  324. void    ccpyhex(char *cptr, long v)
  325. {
  326.     cptr[0] = 0;
  327.     ccathex(cptr, v);
  328. }
  329.  
  330.  
  331.  
  332. /*****************************************************************************/
  333.  
  334.  
  335.  
  336. void    ccpypadnum(char *cptr, char padChr, short minApnd, short maxApnd, long v, short base)
  337. {
  338.     pcpypadnum((StringPtr)cptr, padChr, minApnd, maxApnd, v, base);
  339.     p2c((StringPtr)cptr);
  340. }
  341.  
  342. void    ccpynum(char *cptr, long v, short base)
  343. {
  344.     pcpynum((StringPtr)cptr, v, base);
  345.     p2c((StringPtr)cptr);
  346. }
  347.  
  348.  
  349.  
  350. /*****************************************************************************/
  351. /*****************************************************************************/
  352. /*****************************************************************************/
  353.  
  354.  
  355.  
  356. long    c2dec(char *cptr, short *charsUsed)
  357. {
  358.     return(c2num(cptr, 10, charsUsed));
  359. }
  360.  
  361.  
  362.  
  363. /*****************************************************************************/
  364.  
  365.  
  366.  
  367. long    c2hex(char *cptr, short *charsUsed)
  368. {
  369.     return(c2num(cptr, 16, charsUsed));
  370. }
  371.  
  372.  
  373.  
  374. /*****************************************************************************/
  375.  
  376.  
  377.  
  378. long    c2num(char *cptr, short base, short *charsUsed)
  379. {
  380.     Boolean    firstDigit;
  381.     short    i, sgn;
  382.     short    c;
  383.     long    val;
  384.  
  385.     sgn = 1;
  386.     for (firstDigit = false, val = 0, i = 0;;) {
  387.         c = cptr[i++];
  388.         if (base == 256) {
  389.             if (!c) break;
  390.             if (c == '\'') {
  391.                 ++i;
  392.                 break;
  393.             }
  394.             val *= base;
  395.             val += c;
  396.             continue;
  397.         }
  398.         if (c == '-') {
  399.             if (firstDigit) break;
  400.             if (sgn == -1)  break;
  401.             sgn = -1;
  402.             continue;
  403.         }
  404.         if (c == '$') {
  405.             if (firstDigit) break;
  406.             base = 16;
  407.             continue;
  408.         }
  409.         if (gHandleChars) {
  410.             if (c == '\'') {
  411.                 if (firstDigit) break;
  412.                 base = 256;
  413.                 continue;
  414.             }
  415.         }
  416.         if ((!firstDigit) && (c == ' ')) continue;
  417.         c -= '0';
  418.         if (c > 16) c -= 7;        /* Make 'A' a 10, etc. */
  419.         if (c > 32) c -= 32;    /* Make lower-case upper-case. */
  420.         if (c < 0) break;
  421.         if (c >= base) break;
  422.         val *= base;
  423.         val += (c * sgn);
  424.         firstDigit = true;
  425.     }
  426.  
  427.     if (charsUsed) *charsUsed = --i;
  428.  
  429.     gBase = base;
  430.     return(val);
  431. }
  432.  
  433.  
  434.  
  435. /*****************************************************************************/
  436.  
  437.  
  438.  
  439. short    GetLastBase(Boolean handleChars)
  440. {
  441.     gHandleChars = handleChars;
  442.     return(gBase);
  443. }
  444.  
  445.  
  446.  
  447. /*****************************************************************************/
  448. /*****************************************************************************/
  449. /*****************************************************************************/
  450.  
  451.  
  452.  
  453. /* Catenate a single character multiple times onto the designated string. */
  454.  
  455. void    pcatchr(StringPtr pptr, char c, short count)
  456. {
  457.     while (count--) pptr[++(pptr[0])] = c;
  458. }
  459.  
  460.  
  461.  
  462. /*****************************************************************************/
  463.  
  464.  
  465.  
  466. void    pcatpaddec(StringPtr pptr, char padChr, short minApnd, short maxApnd, long v)
  467. {
  468.     pcatpadnum(pptr, padChr, minApnd, maxApnd, v, -10);
  469. }
  470.  
  471. void    pcatdec(StringPtr pptr, long v)
  472. {
  473.     pcatnum(pptr, v, -10);
  474. }
  475.  
  476.  
  477.  
  478. /*****************************************************************************/
  479.  
  480.  
  481.  
  482. void    pcatpadhex(StringPtr pptr, char padChr, short minApnd, short maxApnd, long v)
  483. {
  484.     char    str[33];
  485.  
  486.     ccpypadhex(str, padChr, minApnd, maxApnd, v);
  487.     c2p(str);
  488.     pcat(pptr, (StringPtr)str);
  489. }
  490.  
  491. void    pcathex(StringPtr pptr, long v)
  492. {
  493.     pcatpadhex(pptr, 0, 0, 8, v);
  494. }
  495.  
  496.  
  497.  
  498. /*****************************************************************************/
  499.  
  500.  
  501.  
  502. long    pcatnum(StringPtr pptr, long v, short base)
  503. {
  504.     unsigned long    j, vv;
  505.  
  506.     vv = v;
  507.     if (base < 0) {
  508.         base = -base;
  509.         if (v < 0) {
  510.             pptr[++*pptr] = '-';
  511.             vv = -vv;
  512.         }
  513.     }
  514.     j = 0;
  515.     if (vv >= base)
  516.         j = pcatnum(pptr, vv / base, base);
  517.  
  518.     pptr[++*pptr] = "0123456789ABCDEF"[vv - j];
  519.     return(base * vv);
  520. }
  521.  
  522. void    pcatpadnum(StringPtr pptr, char padChr, short minApnd, short maxApnd, long v, short base)
  523. {
  524.     Str32    str;
  525.  
  526.     pcpynum(str, v, base);        /* Generate minimum-digit hex value. */
  527.  
  528.     if (str[0] > maxApnd) str[0] = maxApnd;
  529.  
  530.     if (str[0] < minApnd)
  531.         if (padChr)
  532.             pcatchr(pptr, padChr, (minApnd - str[0]));
  533.                 /* if we have a pad character, and if necessary, pad the string. */
  534.  
  535.     pcat(pptr, str);            /* Add the hex digits to the string. */
  536. }
  537.  
  538.  
  539.  
  540. /*****************************************************************************/
  541.  
  542.  
  543.  
  544. void    pcpychr(StringPtr pptr, char c, short count)
  545. {
  546.     pptr[0] = 0;
  547.     pcatchr(pptr, c, count);
  548. }
  549.  
  550.  
  551.  
  552. /*****************************************************************************/
  553.  
  554.  
  555.  
  556. void    pcpypaddec(StringPtr pptr, char padChr, short minApnd, short maxApnd, long v)
  557. {
  558.     *pptr = 0;
  559.     pcatpaddec(pptr, padChr, minApnd, maxApnd, v);
  560. }
  561.  
  562. void    pcpydec(StringPtr pptr, long v)
  563. {
  564.     *pptr = 0;
  565.     pcatdec(pptr, v);
  566. }
  567.  
  568.  
  569.  
  570. /*****************************************************************************/
  571.  
  572.  
  573.  
  574. void    pcpypadnum(StringPtr pptr, char padChr, short minApnd, short maxApnd, long v, short base)
  575. {
  576.     *pptr = 0;
  577.     pcatpadnum(pptr, padChr, minApnd, maxApnd, v, base);
  578. }
  579.  
  580. void    pcpynum(StringPtr pptr, long v, short base)
  581. {
  582.     *pptr = 0;
  583.     pcatnum(pptr, v, base);
  584. }
  585.  
  586.  
  587.  
  588. /*****************************************************************************/
  589.  
  590.  
  591.  
  592. void    pcpypadhex(StringPtr pptr, char padChr, short minApnd, short maxApnd, long v)
  593. {
  594.     *pptr = 0;
  595.     pcatpadhex(pptr, padChr, minApnd, maxApnd, v);
  596. }
  597.  
  598. void    pcpyhex(StringPtr pptr, long v)
  599. {
  600.     pcpypadhex(pptr, 0, 0, 8, v);
  601. }
  602.  
  603.  
  604.  
  605. /*****************************************************************************/
  606.  
  607.  
  608.  
  609. long    p2dec(StringPtr pptr, short *charsUsed)
  610. {
  611.     return(p2num(pptr, 10, charsUsed));
  612. }
  613.  
  614.  
  615.  
  616. /*****************************************************************************/
  617.  
  618.  
  619.  
  620. long    p2hex(StringPtr pptr, short *charsUsed)
  621. {
  622.     return(p2num(pptr, 16, charsUsed));
  623. }
  624.  
  625.  
  626.  
  627. /*****************************************************************************/
  628.  
  629.  
  630.  
  631. long    p2num(StringPtr pptr, short base, short *charsUsed)
  632. {
  633.     long    val;
  634.  
  635.     p2c(pptr);
  636.     val = c2num((char *)pptr, base, charsUsed);
  637.     c2p((char *)pptr);
  638.     return(val);
  639. }
  640.  
  641.  
  642.  
  643. /*****************************************************************************/
  644. /*****************************************************************************/
  645. /*****************************************************************************/
  646.  
  647.  
  648.  
  649. short    GetHexByte(char *cptr)
  650. {
  651.     short    val, i, chr;
  652.  
  653.     for (val = 0, i = 0; i < 2; ++i) {
  654.         chr = cptr[i];
  655.         if (chr == '=') return(cptr[++i]);
  656.         if (chr == '≈') {
  657.             chr = cptr[++i];
  658.             if ((chr >= 'a') && (chr <= 'z')) chr -= 32;
  659.             return(chr);
  660.         }
  661.         if (chr > 'F')
  662.             chr -= 0x20;
  663.         if (chr > '9')
  664.             chr -= ('A' - '9' - 1);
  665.         val = (val << 4) + chr - '0';
  666.     }
  667.     return(val);
  668. }
  669.  
  670.  
  671.  
  672. /*****************************************************************************/
  673.  
  674.  
  675.  
  676. Boolean    EqualHandle(void *h1, void *h2)
  677. {
  678.     long    s1, s2;
  679.     Ptr        p1, p2;
  680.  
  681.     if ((h1) && (!h2)) return(false);
  682.     if ((h2) && (!h1)) return(false);
  683.     if ((s1 = GetHandleSize(h1)) != (s2 = GetHandleSize(h2))) return(false);
  684.  
  685.     p1 = *(Handle)h1;
  686.     p2 = *(Handle)h2;
  687.     for (s1 = 0; s1 < s2; ++s1)
  688.         if (p1[s1] != p2[s1]) return(false);
  689.         
  690.     return(true);
  691. }
  692.  
  693.  
  694.  
  695. /*****************************************************************************/
  696.  
  697.  
  698.  
  699. Boolean    EqualData(void *v1, void *v2, long size)
  700. {
  701.     Ptr        p1, p2;
  702.     long    ii;
  703.  
  704.     if ((v1) && (!v2)) return(false);
  705.     if ((v2) && (!v1)) return(false);
  706.  
  707.     p1 = (Ptr)v1;
  708.     p2 = (Ptr)v2;
  709.     for (ii = 0; ii < size; ++ii)
  710.         if (p1[ii] != p2[ii]) return(false);
  711.         
  712.     return(true);
  713. }
  714.  
  715.  
  716.  
  717. /*****************************************************************************/
  718.  
  719.  
  720.  
  721. void    SetMem(void *vptr, unsigned char c, unsigned long len)
  722. {
  723.     Ptr    ptr;
  724.  
  725.     ptr = (Ptr)vptr;
  726.     while (len--) *ptr++ = c;
  727. }
  728.  
  729.  
  730.  
  731.